package com.service.business.member.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.service.business.base.constants.RedisKeyConstants;
import com.service.business.base.controller.req.VerifyCodeReq;
import com.service.business.base.enums.SmsTypeEnum;
import com.service.business.base.enums.VerifyCodeEnum;
import com.service.business.base.service.ConfigService;
import com.service.business.base.service.VerifyCodeService;
import com.service.business.email.MailService;
import com.service.business.member.service.MemberGradeConfigService;
import com.service.business.member.service.MemberService;
import com.service.business.message.MessageSender;
import com.service.business.order.service.OrderProductHrComboService;
import com.service.dao.dto.MemberGradeCheckDto;
import com.service.business.support.MemCache;
import com.service.core.exception.CommonException;
import com.service.dao.constants.ConfigConstants;
import com.service.dao.enums.CoinsEnum;
import com.service.dao.enums.GradeEnum;
import com.service.dao.mapper.MemberGradeConfigMapper;
import com.service.dao.model.Member;
import com.service.dao.model.MemberGradeConfig;
import com.service.dao.model.SysConfig;
import com.service.dao.po.MemberCache;
import com.service.utility.common.EmailUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.Comparator;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * @author lisi
 */
@Service("memberGradeService")
@Slf4j
public class MemberGradeConfigServiceImpl extends ServiceImpl<MemberGradeConfigMapper, MemberGradeConfig> implements MemberGradeConfigService {

    @Autowired
    private MemberService memberService;

    @Autowired
    private OrderProductHrComboService orderProductHrComboService;

    @Autowired
    private ConfigService sysConfigService;

    @Autowired
    private MessageSender messageSender;

    @Autowired
    private MailService mailService;

    @Autowired
    private VerifyCodeService verifyCodeService;

    @Autowired
    private MemCache memCache;

    @Override
    public void isValidWithdraw(Member member, CoinsEnum coins, BigDecimal todayWithdrawNum) {
        MemberGradeConfig gradeConfig = getById(member.getVipGrade());
        switch (coins) {
            case BTC:
                if (todayWithdrawNum.compareTo(gradeConfig.getWithdrawLimitDailyBtc()) >= 0) {
                    throw new CommonException("今日提现额度已满", "withdraw_fail_by_limit_enough");
                }
                break;
            case ETH:
                if (todayWithdrawNum.compareTo(gradeConfig.getWithdrawLimitDailyEth()) >= 0) {
                    throw new CommonException("今日提现额度已满", "withdraw_fail_by_limit_enough");
                }
                break;
            case USDT:
                if (todayWithdrawNum.compareTo(gradeConfig.getWithdrawLimitDailyUsdt()) >= 0) {
                    throw new CommonException("今日提现额度已满", "withdraw_fail_by_limit_enough");
                }
                break;
            case EXDF:
                if (todayWithdrawNum.compareTo(gradeConfig.getWithdrawLimitDailyExdf()) >= 0) {
                    throw new CommonException("今日提现额度已满", "withdraw_fail_by_limit_enough");
                }
                break;
            case USDF:
                if (todayWithdrawNum.compareTo(gradeConfig.getWithdrawLimitDailyUsdf()) >= 0) {
                    throw new CommonException("今日提现额度已满", "withdraw_fail_by_limit_enough");
                }
                break;
            case FIL:
                if (todayWithdrawNum.compareTo(gradeConfig.getWithdrawLimitDailyFil()) >= 0) {
                    throw new CommonException("今日提现额度已满", "withdraw_fail_by_limit_enough");
                }
                break;
            case XCH:
                if (todayWithdrawNum.compareTo(gradeConfig.getWithdrawLimitDailyFil()) >= 0) {
                    throw new CommonException("今日提现额度已满", "withdraw_fail_by_limit_enough");
                }
                break;
            default:
                throw new CommonException("Unexpected value: " + coins);
        }
    }


    public boolean isTimeLimit() {
        return true;
    }

    @Override
    public Map<Integer, MemberGradeConfig> list2Map() {
        return list().stream().collect(Collectors.toMap(MemberGradeConfig::getId, a -> a));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer checkMemberGrade(MemberCache memberCache) {
        Member member = memberService.getById(memberCache.getMemberId());
        if (ObjectUtils.nullSafeEquals(member.getVipGrade(), GradeEnum.six.getValue())
                || member.getVipGrade() >= GradeEnum.eleven.getValue()) {
            return member.getVipGrade();
        }

        Map<Integer, MemberGradeConfig> gradeConfigMap = list2Map();
        MemberGradeConfig config = gradeConfigMap.get(member.getVipGrade() + 1);
        log.info("会员<{}>检测会员等级，原有等级：{}", memberCache.getMemberId(), memberCache.getMemberGrade());
        if (ObjectUtils.isEmpty(config)) {
            return member.getVipGrade();
        }

        Integer upgradeGradeMemberCounts = memberService.countValidMemberByPath(member.getId(), member.getVipGrade());
        log.info("会员<{}>检测会员等级，会员业绩：{}，与会员等级相等的伞下会员数量：{}", memberCache.getMemberId(), memberCache.getTotalConsumption(), upgradeGradeMemberCounts);
        if (memberCache.getTotalConsumption().compareTo(config.getTotalConsumption()) >= 0
                && checkConfigGradeLimit(config, upgradeGradeMemberCounts)) {
            return config.getId();
        }

        return member.getVipGrade();
//        log.info("会员<{}>检测会员等级，原有等级：{}", memberCache.getMemberId(), memberCache.getMemberGrade());
//        Member member = memberService.getById(memberCache.getMemberId());
//        if (ObjectUtils.nullSafeEquals(member.getVipGrade(), GradeEnum.eleven.getValue())
//                || ObjectUtils.nullSafeEquals(member.getVipGrade(), GradeEnum.four.getValue())) {
//            return member.getVipGrade();
//        }
//        List<Member> teamMemberList = memberService.selectByPathAndStatus(member.getId());
//        BigDecimal totalConsumer = BigDecimal.ZERO;
//        if (!ObjectUtils.isEmpty(teamMemberList)) {
//            List<Integer> teamMemberIdList = teamMemberList.parallelStream().map(Member::getId).collect(Collectors.toList());
//            totalConsumer = orderProductHrComboService.totalEffectiveOrderByMemberList(teamMemberIdList);
//        }
//        Integer memberVipGrade = checkCondition(member, totalConsumer);
//        log.info("会员<{}>检测会员等级，现有等级：{}", memberCache.getMemberId(), memberVipGrade);
//        memberService.updateMemberGrade(member.getId(),memberVipGrade);
//        return memberVipGrade;
    }


    /**
     *
     * @param config
     * @param sameGradeMembers
     * @return
     */
    private boolean checkConfigGradeLimit(MemberGradeConfig config,Integer sameGradeMembers) {
        switch (config.getId()) {
            case 3:
            case 13:
                return sameGradeMembers > config.getVipGradeOneNumLimit();
            case 4:
            case 14:
                return sameGradeMembers > config.getVipGradeTwoNumLimit();
            case 5:
            case 15:
                return sameGradeMembers > config.getVipGradeThreeNumLimit();
            case 6:
            case 16:
                return sameGradeMembers > config.getVipGradeFourNumLimit();
            default:
                return false;
        }
    }


    @Override
    public MemberGradeConfig getByCheckGradeDto(MemberGradeConfig config) {
        return baseMapper.getConfByParams(config);
    }

    private boolean smallMarketValidMember(List<Integer> memberList, Integer smallMarketLimit) {
        if (smallMarketLimit == 0) {
            return true;
        }

        if (ObjectUtils.isEmpty(memberList)) {
            return false;
        }

        List<Integer> validMemberList = memberList.stream().map(item -> memberService.countValidMemberByPath(item, GradeEnum.two.getValue()))
                .sorted(Comparator.reverseOrder()).collect(Collectors.toList());
        IntSummaryStatistics statistics = validMemberList.stream().mapToInt(item -> item).summaryStatistics();

        if (statistics.getSum() == 0) {
            return false;
        }

        return Math.toIntExact(statistics.getSum() - statistics.getMax()) >= smallMarketLimit;
    }

    private Integer checkCondition(Member member, BigDecimal totalConsumer) {
        SysConfig sysTeamComConfig = sysConfigService.getByName(ConfigConstants.FIL_TEAM_BUSINESS_MEETS_STANDARDS_COM_NUM);
        SysConfig sysTeamProxyConfig = sysConfigService.getByName(ConfigConstants.FIL_TEAM_BUSINESS_MEETS_STANDARDS_PROXY_NUM);
        if(member.getVipGrade() >= GradeEnum.eleven.getValue()){
            return member.getVipGrade();
        }
        BigDecimal totalPayMoney = orderProductHrComboService.totalEffectiveHrRateLargeThanZeroByMemberId(member.getId());
//        if(totalConsumer.compareTo(BigDecimal.ZERO) == 0){
//            //普通等级 1
//            if(!ObjectUtils.nullSafeEquals(member.getVipGrade(), GradeEnum.one.getValue()) &&
//                    !ObjectUtils.nullSafeEquals(member.getVipGrade(), GradeEnum.eleven.getValue())){
//                member.setVipGrade(GradeEnum.one.getValue());
//            }
//        }else
        if(totalPayMoney.compareTo(BigDecimal.ZERO) > 0 && totalConsumer.compareTo(BigDecimal.ZERO) > 0 && totalConsumer.compareTo(new BigDecimal(sysTeamProxyConfig.getConfValue())) < 0){
            //普通等级 2
            if(!ObjectUtils.nullSafeEquals(member.getVipGrade(), GradeEnum.two.getValue()) &&
                    !ObjectUtils.nullSafeEquals(member.getVipGrade(), GradeEnum.twelve.getValue())){
                member.setVipGrade(GradeEnum.two.getValue());
            }
        }else if(totalPayMoney.compareTo(BigDecimal.ZERO) > 0 && totalConsumer.compareTo(new BigDecimal(sysTeamProxyConfig.getConfValue())) >= 0
                && totalConsumer.compareTo(new BigDecimal(sysTeamComConfig.getConfValue())) < 0){
            //代理商等级 3
            //发送短信提示申请代理商分红资格
            if(!ObjectUtils.nullSafeEquals(member.getVipGrade(), GradeEnum.three.getValue())
                  && !ObjectUtils.nullSafeEquals(member.getVipGrade(), GradeEnum.thirteen.getValue())){
                //sendNotify("代理商",member);
                member.setVipGrade(GradeEnum.three.getValue());
            }
        }else if(totalPayMoney.compareTo(BigDecimal.ZERO) > 0 && totalConsumer.compareTo(new BigDecimal(sysTeamComConfig.getConfValue())) >= 0){
            //分公司等级 4
            //发送短信提示申请分公司分红资格
            if(!ObjectUtils.nullSafeEquals(member.getVipGrade(), GradeEnum.four.getValue())
                  && !ObjectUtils.nullSafeEquals(member.getVipGrade(), GradeEnum.fourteen.getValue())){
//                sendNotify("分公司",member);
                member.setVipGrade(GradeEnum.four.getValue());
            }
        }
        return member.getVipGrade();
    }

    public void sendNotify(String typeName,Member member){
        String catchType = memCache.get(RedisKeyConstants.NOTIFY_MSG + typeName + member.getUserAccount());
        if(ObjectUtils.isEmpty(catchType) || !typeName.equals(catchType)){
            boolean isEmail = EmailUtil.isEmail(member.getUserAccount());
            VerifyCodeReq verifyCodeReq = new VerifyCodeReq();
            verifyCodeReq.setAccount(member.getUserAccount());
            verifyCodeReq.setCodeType(SmsTypeEnum.INFORM);
            if(isEmail){
                mailService.sendNotifyTplEmail(member.getUserAccount(), typeName);
                log.info("发送邮箱至<{}>成功",member.getUserAccount());
                verifyCodeService.insertSendNotifyRecord(verifyCodeReq,typeName, VerifyCodeEnum.EMAIL);
            }else{
                messageSender.send(member.getMobile(), member.getPhoneCode(),"尊敬的"+member.getUserAccount()+"用户，您已达到平台"+typeName+"资格，请联系客服进行分红资格申请。感谢您的使用！",null);
                log.info("发送短信至<{}>成功",member.getUserAccount());
                verifyCodeService.insertSendNotifyRecord(verifyCodeReq,typeName, VerifyCodeEnum.MOBILE_PHONE);
            }
        }
    }
}
